﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

namespace Galaxy.AutoCAD.Tests
{
    public static class EntTools
    {
        public static void Move(this ObjectId id, Point3d sourcePt, Point3d targetPt)
        {
            Vector3d vector = targetPt.GetVectorTo(sourcePt);
            Matrix3d mt = Matrix3d.Displacement(vector);
            DBObject dBObjectOne = id.GetObject(OpenMode.ForWrite);
            Entity ent = dBObjectOne as Entity;
            if (ent != null)
            {
                ent.TransformBy(mt);
                ent.DowngradeOpen();
            }
        }
        public static void Move(this Entity ent, Point3d sourcePt, Point3d targetPt)
        {
            if (ent.IsNewObject)//如果是未被谈驾到数据库中的新实体
            {
                Vector3d vector = targetPt.GetVectorTo(sourcePt);
                Matrix3d mt = Matrix3d.Displacement(vector);
                ent.TransformBy(mt);
            }
            else
            {
                ent.ObjectId.Move(sourcePt, targetPt);
            }
        }
        public static ObjectId Copy(this ObjectId id, Point3d sourcePt, Point3d targetPt)
        {
            Vector3d vector = targetPt.GetVectorTo(sourcePt);
            Matrix3d mt = Matrix3d.Displacement(vector);
            Entity ent = id.GetObject(OpenMode.ForRead) as Entity;
            Entity entCopy = ent.GetTransformedCopy(mt);
            ObjectId copyId = id.Database.AddToModelSpace(entCopy);
            return copyId;
        }
        public static void Rotate(this ObjectId id, Point3d basePt, double angle)
        {
            Matrix3d mt = Matrix3d.Rotation(angle, Vector3d.ZAxis, basePt);
            Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
            ent.TransformBy(mt);
            ent.DowngradeOpen();
        }
        public static void Scale(this ObjectId id, Point3d basePt, double scaleFactor)
        {
            Matrix3d mt = Matrix3d.Scaling(scaleFactor, basePt);
            Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
            ent.TransformBy(mt);
            ent.DowngradeOpen();
        }
        public static ObjectId Mirror(this ObjectId id, Point3d mirrorPt1, Point3d mirrorPt2, bool eraseSourceObject)
        {
            Line3d miLine = new Line3d(mirrorPt1, mirrorPt2);
            Matrix3d mt = Matrix3d.Mirroring(miLine);
            ObjectId mirrorId = id;
            Entity enti = id.GetObject(OpenMode.ForWrite) as Entity;
            if (eraseSourceObject == true)
            {
                enti.TransformBy(mt);
            }
            else
            {
                Entity entCopy = enti.GetTransformedCopy(mt);
                mirrorId = id.Database.AddToModelSpace(entCopy);
            }
            return mirrorId;
        }
        public static ObjectIdCollection Offset(this ObjectId id, double dis)
        {
            ObjectIdCollection ids = new ObjectIdCollection();
            Curve cur = id.GetObject(OpenMode.ForWrite) as Curve;
            if (cur != null)
            {
                try
                {
                    DBObjectCollection offsetCurves = cur.GetOffsetCurves(dis);
                    Entity[] offsetEnts = new Entity[offsetCurves.Count];
                    offsetCurves.CopyTo(offsetEnts, 0);
                    ids = id.Database.AddToModelSpace(offsetEnts);
                }
                catch
                {
                    Application.ShowAlertDialog("无法偏移！");
                }
            }
            else
            {
                Application.ShowAlertDialog("无法偏移！");
            }
            return ids;
        }
        public static ObjectIdCollection ArrayRectang(this ObjectId id, int numRows, int numCols, double disRows, double disCols)
        {
            ObjectIdCollection ids = new ObjectIdCollection();
            Entity ent = id.GetObject(OpenMode.ForRead) as Entity;
            for (int m = 0; m < numRows; m++)
            {
                for (int n = 0; n < numCols; n++)
                {
                    Matrix3d mt = Matrix3d.Displacement(new Vector3d(n * disCols, m * disRows, 0));
                    Entity entCopy = ent.GetTransformedCopy(mt);
                    ObjectId entCopyId = id.Database.AddToModelSpace(entCopy);
                    ids.Add(entCopyId);
                }
            }
            ent.UpgradeOpen();
            ent.Erase();
            return ids;
        }
        public static ObjectIdCollection ArrayPolar(this ObjectId id, Point3d cenPt, int numObj, double angle)
        {
            ObjectIdCollection ids = new ObjectIdCollection();
            Entity ent = (Entity)id.GetObject(OpenMode.ForRead);
            for (int i = 0; i < numObj; i++)
            {
                Matrix3d mt = Matrix3d.Rotation(angle * (i + 1) / numObj, Vector3d.ZAxis, cenPt);
                Entity entCopy = ent.GetTransformedCopy(mt);
                ObjectId entCopyId = id.Database.AddToModelSpace(entCopy);
                ids.Add(entCopyId);
            }
            return ids;
        }
    }
}
